﻿using System;
using System.Reflection;
using Microsoft.SharePoint;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.ExceptionManagement;

namespace Kiiro.Model.EventHandlers.ItemEventHandlers
{
    public class ProjectItemEventReceiver : SPItemEventReceiver
    {
        /// <summary>
        /// Asynchronous After event that occurs after a new item has been added to its containing object.
        /// </summary>
        /// <param name="properties">
        /// A Microsoft.SharePoint.SPItemEventProperties object that represents properties of the event handler.
        /// </param>
        public override void ItemAdded ( SPItemEventProperties properties )
        {
            try
            {
                if ( properties != null && properties.ListItem != null )
                {
                    Project project = SPDataHelpers.MakeProject ( properties.ListItem );

                    if ( project != null && project.ProjectStatus != ProjectStatus.Closed )
                    {
                        LicensingModel.IncrementOpenProjectCount ( properties.SiteId, properties.RelativeWebUrl );

                        #region Activity History

                        ActivityHistory activity = new ActivityHistory ( project );
                        activity.EditType = EditType.Created;
                        activity.EventType = EventType.Created;
                        activity.ActivityItemType = ItemType.Project;

                        if ( string.IsNullOrEmpty ( activity.ActivityReferenceUrl ) )
                            activity.ActivityReferenceUrl = properties.ListItem.Folder.ServerRelativeUrl;

                        if ( activity != null )
                            ActivityHistoryModel.Save ( activity, properties.SiteId, properties.RelativeWebUrl );

                        #endregion
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( new Exception ( String.Format ( "Exception in: {0}\r\n {1}", MethodInfo.GetCurrentMethod ( ).Name, ex.ToString ( ) ) ), true );
            }

            base.ItemAdded ( properties );
        }

        /// <summary>
        /// Synchronous Before event that occurs when an existing item is changed, for example, when the user changes data in one or more fields.
        /// </summary>
        /// <param name="properties">
        /// A Microsoft.SharePoint.SPItemEventProperties object that represents properties of the event handler.
        /// </param>
        public override void ItemUpdating ( SPItemEventProperties properties )
        {
            try
            {
                if ( properties != null && properties.ListItem != null )
                {
                    Project project = SPDataHelpers.MakeProject ( properties.ListItem );

                    if ( project != null )
                    {
                        ProjectStatus currentStatus = project.ProjectStatus;
                        ProjectStatus newStatus = project.ProjectStatus;

                        if ( properties.AfterProperties [ Constants.ProjectFieldNames.ProjectStatus ] != null )
                            newStatus = SPDataHelpers.GetProjectStatusValue ( properties.AfterProperties, Constants.ProjectFieldNames.ProjectStatus );

                        if ( currentStatus != newStatus && ( currentStatus == ProjectStatus.Closed || newStatus == ProjectStatus.Closed ) )
                        {
                            // update midori property bag
                            if ( newStatus != ProjectStatus.Closed )
                            {
                                properties.Cancel = LicensingModel.IncrementOpenProjectCount ( properties.SiteId, properties.RelativeWebUrl );
                            }
                            else
                            {
                                LicensingModel.DecrementOpenProjectCount ( properties.SiteId, properties.RelativeWebUrl );
                            }
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( new Exception ( String.Format ( "Exception in: {0}\r\n {1}", MethodInfo.GetCurrentMethod ( ).Name, ex.ToString ( ) ) ), true );
            }

            if ( !properties.Cancel )
                base.ItemUpdating ( properties );
        }

        /// <summary>
        /// Asynchronous After event that occurs after an existing item is changed, for example, when the user changes data in one or more fields.
        /// </summary>
        /// <param name="properties">
        /// A Microsoft.SharePoint.SPItemEventProperties object that represents properties of the event handler.
        /// </param>
        public override void ItemUpdated ( SPItemEventProperties properties )
        {
            try
            {
                if ( properties != null && properties.ListItem != null )
                {
                    ActivityHistory activity = null;

                    Project project = SPDataHelpers.MakeProject ( properties.ListItem );

                    if ( project != null )
                    {
                        if ( project.PlanDirty )
                        {
                            properties.ListItem [ Constants.ProjectFieldNames.PlanDirty ] = false;

                            activity = new ActivityHistory ( project );
                            activity.EditType = EditType.Created;
                            activity.Title = "";
                            activity.ActivityItemType = ItemType.ProjectPlan;
                            activity.EventType = EventType.Synced;

                            using ( SPWeb web = properties.ListItem.Web )
                            {
                                web.AllowUnsafeUpdates = true;
                                this.DisableEventFiring ( );
                                properties.ListItem.Update ( );
                                this.EnableEventFiring ( );
                                web.AllowUnsafeUpdates = false;
                            }

                            if ( string.IsNullOrEmpty ( activity.ActivityReferenceUrl ) )
                                activity.ActivityReferenceUrl = properties.ListItem.Folder.ServerRelativeUrl;

                            if ( activity != null )
                            {
                                // -- Save to Project's Activity History List --
                                ActivityHistoryModel.Save ( activity, properties.SiteId, project.ServerRelativeWebUrl );
                            }
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( new Exception ( String.Format ( "Exception in: {0}\r\n {1}", MethodInfo.GetCurrentMethod ( ).Name, ex.ToString ( ) ) ), true );
            }

            base.ItemUpdated ( properties );
        }

        #region Unused

        /// <summary>
        /// Synchronous Before event that occurs when a new item is added to its containing object.
        /// </summary>
        /// <param name="properties">
        /// A Microsoft.SharePoint.SPItemEventProperties object that represents properties of the event handler.
        /// </param>
        public override void ItemAdding ( SPItemEventProperties properties )
        {
            base.ItemAdding ( properties );
        }

        /// <summary>
        /// Synchronous Before event that occurs before an existing item is completely deleted.
        /// </summary>
        /// <param name="properties">
        /// A Microsoft.SharePoint.SPItemEventProperties object that represents properties of the event handler.
        /// </param>
        public override void ItemDeleting ( SPItemEventProperties properties )
        {
            base.ItemDeleting ( properties );
        }

        /// <summary>
        /// Asynchronous After event that occurs after an existing item is completely deleted.
        /// </summary>
        /// <param name="properties">
        /// A Microsoft.SharePoint.SPItemEventProperties object that represents properties of the event handler.
        /// </param>
        public override void ItemDeleted ( SPItemEventProperties properties )
        {
            base.ItemDeleted ( properties );
        }

        #endregion
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Model/EventHandlers/ItemEventHandlers/ProjectItemEventReceiver.cs $
 * 
 * 5     6/11/09 12:40p Camerons
 * 
 * 4     17/08/09 10:29a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/